using UnityEngine;
using System.Collections.Generic;

using Unity.Collections;
using Unity.Jobs;

namespace  Example_Sample_02
{
    // Job adding two floating point values together
    public class test:MonoBehaviour
    {
        

        private void Start() {
           
        }
        /// <summary>
        /// OnGUI is called for rendering and handling GUI events.
        /// This function can be called multiple times per frame (one call per event).
        /// </summary>
        void OnGUI()
        {
            if(GUILayout.Button("ScheduleJob")){
                ScheduleJob();
            }

            if(GUILayout.Button("JobHandle和依赖关系")){
                ScheduleJob2();
            }

            if(GUILayout.Button("结合依赖关系")){
                ScheduleJob3();
            }

            if(GUILayout.Button("多个Jobs和dependencies的示例")){
                ScheduleJob4();
            }

            
        }


        void ScheduleJob(){
            // Create a native array of a single float to store the result. This example waits for the job to complete for illustration purposes
            NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);

            // Set up the job data
            MyJob jobData = new MyJob();
            jobData.a = 10;
            jobData.b = 10;
            jobData.result = result;

            // Schedule the job
            JobHandle handle = jobData.Schedule();

            // Wait for the job to complete
            handle.Complete();

            // All copies of the NativeArray point to the same memory, you can access the result in "your" copy of the NativeArray
            float aPlusB = result[0];

            Debug.LogError("aPlusB: "+aPlusB);
            // Free the memory allocated by the result array
            result.Dispose();

        }

        void ScheduleJob2(){
            // Create a native array of a single float to store the result. This example waits for the job to complete for illustration purposes
            NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
            NativeArray<float> result2 = new NativeArray<float>(1, Allocator.TempJob);

            // Set up the job data
            MyJob jobData = new MyJob();
            jobData.a = 10;
            jobData.b = 10;
            jobData.result = result;

            // Set up the job data
            MyJob secondJob  = new MyJob();
            secondJob.a = 10;
            secondJob.b = 12;
            secondJob.result = result2;

            // Schedule the job
            JobHandle handle = jobData.Schedule();
            JobHandle secondHandle =  secondJob.Schedule(handle); //当您调用作业的Schedule方法时，它将返回JobHandle。您可以在代码中使用JobHandle 作为其他Job的依赖关系。
                                                                  //如果Job取决于另一个Job的结果，您可以将第一个作业JobHandle作为参数传递给第二个作业的Schedule方法，如下所示：
            // Wait for the job to complete
            secondHandle.Complete();

            // All copies of the NativeArray point to the same memory, you can access the result in "your" copy of the NativeArray
            float aPlusB = result[0];
            float second_aPlusB = result2[0];

            Debug.LogError("aPlusB: "+aPlusB);
            Debug.LogError("aPlusB2: "+second_aPlusB);


            // Free the memory allocated by the result array
            result.Dispose();
            result2.Dispose();
        }

        //如果作业有许多依赖项，则可以使用JobHandle.CombineDependencies方法合并它们。CombineDependencies允许您将它们传递给Schedule方法。
        void ScheduleJob3(){
            
            int jobCount = 56;
            

            List<NativeArray<float>> list = new List<NativeArray<float>>();

            NativeArray<JobHandle> handles = new NativeArray<JobHandle>(jobCount, Allocator.TempJob);
            for(int i = 0;i<jobCount;i++){

                NativeArray<float> result = new NativeArray<float>(jobCount, Allocator.TempJob);
                MyJob jobData = new MyJob();
                jobData.a = i;
                jobData.b = 0;

                jobData.result = result;
                list.Add(result);

                JobHandle _jobHandle =  jobData.Schedule();
                handles[i] = _jobHandle;
            }
            JobHandle jobHandle = JobHandle.CombineDependencies(handles);
            jobHandle.Complete();

            for(int i=0;i<jobCount;i++){
                Debug.LogError("i: "+i +" result:"+list[i][0]);
                list[i].Dispose();
            }

            

            

            handles.Dispose();
            // Free the memory allocated by the result array
            
 
        }
        //多个Jobs和dependencies的示例
        void ScheduleJob4(){
            // Create a native array of a single float to store the result in. This example waits for the job to complete
            NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);

            // Setup the data for job #1
            MyJob jobData = new MyJob();
            jobData.a = 10;
            jobData.b = 10;
            jobData.result = result;

            // Schedule job #1
            JobHandle firstHandle = jobData.Schedule();

            // Setup the data for job #2
            AddOneJob incJobData = new AddOneJob();
            incJobData.result = result;

            // Schedule job #2
            JobHandle secondHandle = incJobData.Schedule(firstHandle);

            // Wait for job #2 to complete
            secondHandle.Complete();

            // All copies of the NativeArray point to the same memory, you can access the result in "your" copy of the NativeArray
            float aPlusB = result[0];
            Debug.LogError("aPlusB: "+aPlusB);
            // Free the memory allocated by the result array
            result.Dispose();

        }

    }

}